package com.moyun.controller.system;


import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.moyun.common.annotation.OperLog;
import com.moyun.common.aspect.BusinessType;
import com.moyun.common.enums.CodeEnum;
import com.moyun.model.common.R;
import com.moyun.model.po.system.SysMenuEntity;
import com.moyun.service.system.SysMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 系统菜单表 前端控制器
 * </p>
 *
 * @author yangboxuan
 * @since 2021-07-01
 */
@ApiSupport(order = 998)
@Api(tags = "系统菜单")
@RestController
@RequestMapping("/security/sys-menu")
public class SysMenuController {
    @Autowired
    private SysMenuService sysMenuEntityService;

    /**
     * @return com.moyun.model.common.R
     * @Author yangboxuan
     * @Description 获取系统菜单
     * @Date 2023/1/3 15:40
     * @Param []
     **/
    @ApiOperation("系统菜单(树查询)")
    @PostMapping({"list"})
    @OperLog(operModul = "菜单模块", operType = BusinessType.QUERY, operDesc = "分页查询")
    public R list() {
        List<SysMenuEntity> records = this.sysMenuEntityService.list();
        // 构建node列表
        List<TreeNode<Integer>> nodeList = records.stream().map(entity -> {
            // 树节点扩展属性(也叫扩展树结点的属性)   树节点本身属性: id parentId(父节点id) name(名称) weight(权重)
            Map<String, Object> map = new HashMap<>();
            map.put("menuPath", entity.getMenuPath());
            map.put("menuDesc", entity.getDesc());
            return new TreeNode<Integer>()
                    .setId(entity.getMenuId())
                    .setParentId(entity.getMenuParentId())
                    .setName(entity.getMenuName())
                    .setWeight(entity.getSortWeight())
                    .setExtra(map);
        }).collect(Collectors.toList());
        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都要默认值的 TreeNode的原有属性名是: id parentId(父节点id) name(名称) weight(权重)
        // 这里改为数据库中存储的字段--实体类属性名
        treeNodeConfig.setIdKey("menuId");
        treeNodeConfig.setParentIdKey("menuParentId");
        treeNodeConfig.setWeightKey("sortWeight");
        treeNodeConfig.setNameKey("menuName");
        // 最大递归深度
        treeNodeConfig.setDeep(3);
        //转换器
        List<Tree<Integer>> treeNodes = TreeUtil.build(nodeList, 0, treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId());
                    tree.setParentId(treeNode.getParentId());
                    tree.setWeight(treeNode.getWeight());
                    tree.setName(treeNode.getName());
                    // 扩展属性 ...
                    tree.putExtra("menuPath", treeNode.getExtra().getOrDefault("menuPath", null));
                });
        return R.ok(CodeEnum.SUCCESS, treeNodes);

    }

    @ApiOperation("更新系统菜单")
    @PostMapping({"add"})
    @OperLog(operModul = "菜单模块", operType = BusinessType.INSERT, operDesc = "更新系统菜单")
    public R add(@RequestBody @Validated SysMenuEntity sysMenuEntity) {
        if (!ObjectUtils.isEmpty(sysMenuEntity.getMenuId())) {
            SysMenuEntity sme = this.sysMenuEntityService.getById(sysMenuEntity.getMenuId());
            if (ObjectUtils.isEmpty(sme)) {
                return R.error(CodeEnum.FAIL.getCode(), "更新失败,菜单信息有误!");
            }
        }
        return this.sysMenuEntityService.saveOrUpdate(sysMenuEntity) ? R.ok(CodeEnum.SUCCESS.getCode(), "更新成功") : R.error(CodeEnum.FAIL.getCode(), "更新失败");
    }

    @ApiOperation("删除系统菜单")
    @DeleteMapping({"del"})
    @OperLog(operModul = "菜单模块", operType = BusinessType.DELETE, operDesc = "删除菜单")
    public R del(@PathVariable("id") String id) {
        SysMenuEntity sme = this.sysMenuEntityService.getById(id);
        if (ObjectUtils.isEmpty(sme)) {
            return R.error(CodeEnum.FAIL.getCode(), "删除失败,菜单信息有误!");
        }
        return this.sysMenuEntityService.removeById(id) ? R.ok() : R.error();
    }


}

